Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Data
Imports System.IO

''' <summary>
''' This class implements the functionality to store all the Participant 
''' information into a local xml file.
''' </summary>
Class XmlStore
    Const _xmlFileName As String = "dc_data.xml"

    Private Shared Function GetXmlFileFullPath() As String
        Dim assembly_path As String = System.Reflection.Assembly.GetExecutingAssembly().Location
        Dim directory_path As String = Path.GetDirectoryName(assembly_path)
        Dim xml_path As String = Path.Combine(directory_path, _xmlFileName)
        Return xml_path
    End Function

    Private Shared Sub StoreDataSetToXml(ByVal ds As DataSet)
        Dim xml_path As String = GetXmlFileFullPath()
        ds.WriteXml(xml_path, XmlWriteMode.WriteSchema)
    End Sub

    ''' <summary>
    ''' Construct the DataSet from Xml storage
    ''' </summary>
    ''' <returns>DataSet of the Xml stored</returns>
    Public Shared Function ConstructDataSetFromXml() As DataSet
        Dim xml_path As String = GetXmlFileFullPath()
        If (Not File.Exists(xml_path)) Then
            'If the file does not exist. (application run for first time)
            'Create the xml file
            CreateDataSetXmlSource()
        End If
        Dim ds As New DataSet()
        Try
            ds.ReadXml(xml_path)
        Catch e As Exception
            Dim errorMessage As String = "An error occured while reading participant data from " + xml_path
            errorMessage += vbCrLf + vbCrLf + "Error:" + e.Message
            errorMessage += vbCrLf + vbCrLf + "If the error persists, delete the above file and try again."
            System.Windows.Forms.MessageBox.Show(errorMessage)
            Throw
        End Try
        Return ds
    End Function

    ''' <summary>
    ''' Creates the xml storage file with an empty dataset of the required schema
    ''' </summary>
    Private Shared Sub CreateDataSetXmlSource()
        Dim ds As New DataSet("DCAppData")

        Dim objTable As New DataTable("Participants")

        Dim col_1 As New DataColumn("MyAppSpecificParticipantId", GetType(String))
        Dim col_2 As New DataColumn("ParticipantName", GetType(String))
        Dim col_3 As New DataColumn("DateTokenGenerated", GetType(DateTime))
        Dim col_4 As New DataColumn("ParticipantCode", GetType(String))
        Dim col_5 As New DataColumn("SecurityQuestion", GetType(String))
        Dim col_6 As New DataColumn("SecurityAnswer", GetType(String))
        Dim col_7 As New DataColumn("HasAuthorized", GetType(Boolean))
        Dim col_8 As New DataColumn("PersonId", GetType(Guid))
        Dim col_9 As New DataColumn("RecordId", GetType(Guid))

        objTable.Columns.Add(col_1)
        objTable.Columns.Add(col_2)
        objTable.Columns.Add(col_3)
        objTable.Columns.Add(col_4)
        objTable.Columns.Add(col_5)
        objTable.Columns.Add(col_6)
        objTable.Columns.Add(col_7)
        objTable.Columns.Add(col_8)
        objTable.Columns.Add(col_9)

        ds.Tables.Add(objTable)
        StoreDataSetToXml(ds)
    End Sub

    ''' <summary>
    ''' Adds a participant to the xml data storage
    ''' </summary>
    ''' <param name="appSpecificParticipantId">The application specific identifier for the participant.</param>
    ''' <param name="participantName">Name of the participant</param>
    ''' <param name="dateTokenGenerated">Date time of registration</param>
    ''' <param name="participantCode">A token that the participant should use when authorizing this application to use his healthrecord</param>
    ''' <param name="securityQuestion">The security question agreed upon</param>
    ''' <param name="securityAnswer">The security answer agreed upon</param>
    Public Shared Sub AddParticipantToLocalStore(ByVal appSpecificParticipantId As String, _
                        ByVal participantName As String, _
                        ByVal dateTokenGenerated As DateTime, _
                        ByVal participantCode As String, _
                        ByVal securityQuestion As String, _
                        ByVal securityAnswer As String)
        'Construct the dataset from XML first
        Dim ds As DataSet = ConstructDataSetFromXml()

        'Add rows to the table in dataset
        Dim objTable As DataTable = ds.Tables(0)
        Dim newRow As DataRow = objTable.NewRow()
        newRow("MyAppSpecificParticipantId") = appSpecificParticipantId
        newRow("ParticipantName") = participantName
        newRow("DateTokenGenerated") = dateTokenGenerated
        newRow("ParticipantCode") = participantCode
        newRow("SecurityQuestion") = securityQuestion
        newRow("SecurityAnswer") = securityAnswer
        newRow("HasAuthorized") = False

        objTable.Rows.Add(newRow)

        'Store the dataset back to xml
        StoreDataSetToXml(ds)
    End Sub

    ''' <summary>
    ''' Changes the status of a participant once he has authorized the application access in HealthVault shell
    ''' Specifically, updates the participant record in the xml with PersonId, RecordId and sets the HasAuthorized flag to true
    ''' </summary>
    ''' <param name="appSpecificParticipantId">The application specific identifier for the participant.</param>
    ''' <param name="personId">The PersonId that needs to be used in future offline access to this participant record</param>
    ''' <param name="recordId">The RecordId that needs to be used in future offline access to this participant record</param>
    Public Shared Sub UpdateParticipantToAuthorizedStatus(ByVal appSpecificParticipantId As String, _
            ByVal personId As String, ByVal recordId As String)
        Dim ds As DataSet = ConstructDataSetFromXml()
        Dim objTable As DataTable = ds.Tables(0)

        Dim matchingRows As DataRow() = objTable.Select("MyAppSpecificParticipantId='" + appSpecificParticipantId.ToString() + "'")

        If matchingRows.Length > 0 Then
            Dim rowToUpdate As DataRow = matchingRows(0)
            rowToUpdate("PersonId") = personId
            rowToUpdate("RecordId") = recordId
            rowToUpdate("HasAuthorized") = True
        End If
        StoreDataSetToXml(ds)
    End Sub

    ''' <summary>
    ''' Returns the details of a participant in a DataRow corresponding to a participant
    ''' </summary>
    ''' <param name="appSpecificParticipantId">The application specific identifier for the participant.</param>
    ''' <returns>DataRow populated with participant data</returns>
    Public Shared Function FetchParticipantFromLocalStore(ByVal appSpecificParticipantId As String) As DataRow
        Dim ds As DataSet = ConstructDataSetFromXml()
        Dim objTable As DataTable = ds.Tables(0)

        Dim matchingRows As DataRow() = objTable.Select("MyAppSpecificParticipantId='" + appSpecificParticipantId.ToString() + "'")
        If matchingRows.Length > 0 Then
            Dim rowToReturn As DataRow = matchingRows(0)
            Return rowToReturn
        End If
        Return Nothing
    End Function
End Class
